/*------------------------------------------------------------------------------
 * @file    DIGITAL_TUBE.H
 * @author  嵌入式王子
 * @email   donminedm@163.com
 * @date    2024/07/26 21:39:28
 * @brief   开源的嵌入式软件包，本人不对此代码负责任
 * -----------------------------------------------------------------------------*/
#ifndef _DIGITAL_TUBE_H_
#define _DIGITAL_TUBE_H_

#include "delay.h"
#include "main.h"
#include <stdint.h>

/**
 * @brief 最小保持时间
 *
 */
#define __DIGITAL_TUBE_DELAY() delay_us(1)

// 是否启用 138 译码器
#define __DIGITAL_TUBE_HC138 0

/**
 * @brief 74HC138 位选：2^3  范围：0 ~ (2^3 - 1)
 */
#if __DIGITAL_TUBE_HC138
#define __DIGITAL_TUBE_HC138_A0(bit) HAL_GPIO_WritePin(HC138_A0_GPIO_Port, HC138_A0_Pin, bit)
#define __DIGITAL_TUBE_HC138_A1(bit) HAL_GPIO_WritePin(HC138_A1_GPIO_Port, HC138_A1_Pin, bit)
#define __DIGITAL_TUBE_HC138_A2(bit) HAL_GPIO_WritePin(HC138_A2_GPIO_Port, HC138_A2_Pin, bit)
#endif

/**
 * @brief 时钟线定义
 *
 */
typedef enum DIGITAL_TUBE_CLK
{
    DIGITAL_TUBE_SCLK, // 数据时钟
    DIGITAL_TUBE_LCLK  // 锁存时钟
} digital_tube_clk;

// 数据线
#define __DIGITAL_TUBE_DATA(bit) HAL_GPIO_WritePin(SMG_DATA_GPIO_Port, SMG_DATA_Pin, bit)
// 数据时钟线
#define __DIGITAL_TUBE_SCLK(bit) HAL_GPIO_WritePin(SMG_SCK_GPIO_Port, SMG_SCK_Pin, bit)
// 锁存时钟线
#define __DIGITAL_TUBE_LCLK(bit) HAL_GPIO_WritePin(SMG_RCK_GPIO_Port, SMG_RCK_Pin, bit)

/**
 * @brief 数码管位数定义，名称确定为宏定义前缀
 *
 */
typedef enum DIGITAL_TUBE_BITS
{
    SMG_BIT_1 = 0,
    SMG_BIT_2,
    // ……在这扩展其他位数，但命名要遵循规则 DIGITAL_TUBE_BIT_X
    DIGITAL_TUBE_BIT_MAX
} digital_tube_bits;

// __DIGITAL_TUBE_CHOOSE_BIT(SMG_BIT_BIT_1,0) => HAL_GPIO_WritePin(SMG_BIT_BIT_1_GPIO_Port, SMG_BIT_BIT_1_Pin, 0)
#define __DIGITAL_TUBE_CHOOSE_BIT(bit, level) HAL_GPIO_WritePin(bit##_GPIO_Port, bit##_Pin, level)

/**
 * @brief 数码管顺序定义
 *
 */
typedef enum DIGITAL_TUBE_NUM
{
    // DIGITAL_TUBE_0 ~ DIGITAL_TUBE_F, 0~15
    DIGITAL_TUBE_DOT = 16, // 小数点
    DIGITAL_TUBE_NONE,     // 全灭
    DIGITAL_TUBE_SEP,      // 分隔符
                           // …… 其他特殊字符可在后续添加定义：DIGITAL_TUBE_XXX，字符信息添加至 @common_cathode_lib
} digital_tube_num;

/**
 * @brief 数码管初始化
 *
 */
void digital_tube_init(void);

/**
 * @brief 数码管某位显示某字符
 *
 * @param bit 位，第几位数码管 0 - 7
 * @param seg 段，显示什么字符 DIGITAL_TUBE_NUM
 *
 *   digital_tube_set_bit(0,5);
 */
void digital_tube_set_bit(uint8_t seg, uint8_t bit);

/**
 * @brief 数码管清空
 *
 */
void digital_tube_clean();

#endif // !_DIGITAL_TUBE_H_